#!/usr/bin/env python3

# this is a dbus server.
# ps -ef | grep python3 | grep -v grep | awk '{print $2}' | xargs kill -9

import sys, subprocess

from PyQt5.QtCore import QCoreApplication, pyqtSlot, QObject, Q_CLASSINFO
from PyQt5.QtDBus import QDBusAbstractAdaptor, QDBusConnection

def func_run(command):
    str_zenity = "zenity --info --text='{}'".format(command)
    subprocess.call(str_zenity, shell=True)

class Car(QObject):
    def turn_left(self, degree: int):
        func_run("The car turn left [{}] degree.".format(degree))

    def turn_right(self, degree: int):
        func_run("The car turn right [{}] degree.".format(degree))

    def turn_back(self):
        func_run("The car is turnning back.")


class CarInterface(QDBusAbstractAdaptor):
    Q_CLASSINFO("D-Bus Interface", 'org.HallGarden.Examples.Interface')
    Q_CLASSINFO("D-Bus Introspection", ''
            '  <interface name="org.HallGarden.Examples.Interface">\n'
            '    <method name="turn_left">\n'
            '      <arg direction="in" type="i"/>\n'
            '    </method>\n'
            '    <method name="turn_right">\n'
            '      <arg name="degree" direction="in" type="i"/>\n'
            '      <arg name="any" direction="out" type="i"/>\n'
            '    </method>\n'
            '    <method name="turn_back"/>\n'
            '  </interface>\n'
            '')

    def __init__(self, parent):
        super().__init__(parent)
        self.setAutoRelaySignals(True)

    @pyqtSlot(int)
    def turn_left(self, degree):
        self.parent().turn_left(degree)

    @pyqtSlot(int)
    def turn_right(self, degree):
        self.parent().turn_right(degree)
        return 30

    @pyqtSlot()
    def turn_back(self):
        self.parent().turn_back()


if __name__ == "__main__":
    app = QCoreApplication(sys.argv)

    car = Car()
    CarInterface(car)  # 装饰car对象，而新生成的对象并没实际应用

    connection = QDBusConnection.sessionBus()
    connection.registerService('org.example.CarExample')
    connection.registerObject('/Car/test', car)

    sys.exit(app.exec_())